/**
 * Author(s): xuming.Wong <xuming.Wong@gmail.com>
 */

#ifndef __MESH_VERTEX_H__
#define __MESH_VERTEX_H__

#include "GPrerequisites.h"

#include "OgreMath.h"
#include "OgreVertexBoneAssignment.h"

#include "BlenderMeshUtil.h"

namespace GNgine
{
	/*Used for blender
	*/
	class MeshVertex
	{
	public:
		float vertex[3];
		float normal[3];
		Ogre::uint colour;
		float uv[8][2];//eight layer, U,V coord
		int index;
		int layer_max, vba_index;
	public:

		MeshVertex();
		MeshVertex(const MeshVertex& o);

		MeshVertex& operator= (const MeshVertex&o);
		bool operator == (const MeshVertex& o) const;
	};

	inline MeshVertex::MeshVertex()
	{
	}


	inline MeshVertex::MeshVertex(const MeshVertex& o)
	{
		*this= o;
	}

	inline MeshVertex& MeshVertex::operator= (const MeshVertex&o)
	{
		colour= o.colour;
		layer_max= o.layer_max;
		index= o.index;
		vba_index= o.vba_index;

		VEC3CPY(vertex, o.vertex);
		VEC3CPY(normal, o.normal);

		VEC2CPY(uv[0], o.uv[0]);
		VEC2CPY(uv[1], o.uv[1]);
		VEC2CPY(uv[2], o.uv[2]);
		VEC2CPY(uv[3], o.uv[3]);
		VEC2CPY(uv[4], o.uv[4]);
		VEC2CPY(uv[5], o.uv[5]);
		VEC2CPY(uv[6], o.uv[6]);
		VEC2CPY(uv[7], o.uv[7]);

		return *this;
	}

	//Two vertices are equal when position normal color and texture coord are nearly equal
	inline bool MeshVertex::operator == (const MeshVertex& o) const
	{
		bool result= false;

		float d[3];
		VEC3SUB(vertex, o.vertex, d);
		result= fabs(VEC3DOT(d)) < TOL;
		if (!result)
			return false;

		VEC3SUB(normal, o.normal, d);
		result= fabs(VEC3DOT(d)) < TOL;
		if (!result)
			return false;

		result= colour == o.colour;
		if (!result)
			return false;

		float u[2];
		for (int i= 0; i < layer_max; i++){
			VEC2SUB(uv[i], o.uv[i], u);
			result= fabs(VEC2DOT(u)) < TOL;
			if (!result)
				break;
		}

		return result;
	}
}
#endif

